package Controllers;

import Configs.Config;
import GUIs.f_nhanvien_chunhatro_qlgiaphong;
import com.db4o.ObjectSet;
import com.db4o.ext.DatabaseClosedException;
import com.db4o.ext.DatabaseReadOnlyException;
import com.db4o.ext.Db4oIOException;
import com.db4o.query.Predicate;
import com.db4o.query.Query;
import java.awt.HeadlessException;
import java.util.Calendar;
import java.util.Set;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import models.ChiTietGia;
import models.LoaiPhong;

public class LoaiPhongTroController {

    private final Config conn;
    private BieuThucChinhQuy btcq;
    private MyTableFormat myFormat;

    public LoaiPhongTroController(Config conn) {
        this.conn = conn;
    }

    public int generateIDLoaiPhong() {
        Query query = this.conn.getConn().query();
        query.constrain(LoaiPhong.class);
        query.sortBy((LoaiPhong loaiPhongA, LoaiPhong loaiPhongB) -> loaiPhongB.getIdloaiphong() - loaiPhongA.getIdloaiphong());
        try {
            LoaiPhong loaiPhong = (LoaiPhong) query.execute().next();
            int maxIDPhong = loaiPhong.getIdloaiphong() + 1;
            return maxIDPhong;
        } catch (Exception ex) {
            return 1;
        }
    }

    public void setCbbSoNguoi(JComboBox cbbSoNguoi) {
        Query query = this.conn.getConn().query();
        query.constrain(LoaiPhong.class);
        query.sortBy((LoaiPhong loaiPhongTroA, LoaiPhong loaiPhongTroB) -> loaiPhongTroA.getSucchua() - loaiPhongTroB.getSucchua());
        ObjectSet<LoaiPhong> loaiPhongs = query.execute();
        String[] sucChuaTemp = new String[loaiPhongs.size()];
        int i = 0;
        for (LoaiPhong loaiPhong : loaiPhongs) {
            sucChuaTemp[i++] = loaiPhong.getSucchua() + "";
        }
        Set<String> sucChua = XuLyChuoi.xoaTrungMang(sucChuaTemp);
        
        for (String item: sucChua) {
            cbbSoNguoi.addItem(item + " người");
        }
    }

    public void setCbbLoaiPhong(JComboBox cbbLoaiPhong) {
        cbbLoaiPhong.removeAllItems();
        cbbLoaiPhong.addItem("- Chọn loại phòng -");
        Query query = this.conn.getConn().query();
        query.constrain(LoaiPhong.class);
        // query.sortBy((LoaiPhong loaiPhongTroA, LoaiPhong loaiPhongTroB) -> loaiPhongTroA.getSucchua() - loaiPhongTroB.getSucchua());
        ObjectSet<LoaiPhong> loaiPhongs = query.execute();
        loaiPhongs.stream().forEach((LoaiPhong loaiPhong) -> {
            cbbLoaiPhong.addItem(loaiPhong.getMotaloai());
        });
    }

    public void setCbbLoaiPhongWithGPDKKD(JComboBox cbbLoaiPhong, String soGPDKKD) {
        cbbLoaiPhong.removeAllItems();
        cbbLoaiPhong.addItem("- Chọn loại phòng -");
        ObjectSet<ChiTietGia> chiTietGias = this.conn.getConn().query(new Predicate<ChiTietGia>() {

            @Override
            public boolean match(ChiTietGia et) {
                return et.getNhatro().getGPKD().equals(soGPDKKD) && 
                        (DateNTime.compareDate(et.getThoidiemapdung(), Calendar.getInstance().getTime()) == 1 || 
                        DateNTime.compareDate(et.getThoidiemapdung(), Calendar.getInstance().getTime()) == 0);
            }
        });
        int i = 0;
        String[] loaiPhong = new String[chiTietGias.size()];
        for (ChiTietGia chiTietGia : chiTietGias) {
            loaiPhong[i++] = chiTietGia.getLoaiphong().getMotaloai();
        }
        Set<String> loaiPhongKQ = XuLyChuoi.xoaTrungMang(loaiPhong);
          for (String item : loaiPhongKQ) {
             cbbLoaiPhong.addItem(item);
        }
    }

    public LoaiPhong getLoaiPhongWithTen(String tenPhong) {
        return this.conn.getConn().query(new Predicate<LoaiPhong>() {
            @Override
            public boolean match(LoaiPhong et) {
                return et.getMotaloai().equals(tenPhong);
            }
        }).next();
    }

    public void Show(JTable tbdsLoaiPhong) {
        this.myFormat = new MyTableFormat();
        DefaultTableModel model = (DefaultTableModel) tbdsLoaiPhong.getModel();
        int stt = 0;
        ObjectSet<LoaiPhong> loaiPhongs = this.conn.getConn().query(new Predicate<LoaiPhong>() {
            @Override
            public boolean match(LoaiPhong loaiPhong) {
                return !loaiPhong.getIsDel();
            }
        });
        for (LoaiPhong loaiPhong : loaiPhongs) {
            Object[] row = {++stt, loaiPhong.getIdloaiphong(), loaiPhong.getMotaloai(), loaiPhong.getSucchua()};
            model.addRow(row);
        }

        this.myFormat.resizeFitRows(tbdsLoaiPhong);
    }

    public boolean Add(f_nhanvien_chunhatro_qlgiaphong them_loaiphong) {
        int idloaiphong = Integer.parseInt(them_loaiphong.tfidloaiphong.getText());
        String motaloai = XuLyChuoi.inHoaChuDauChuoi(them_loaiphong.tfmotaloaiphong.getText());
        String songuoio = them_loaiphong.cbbsonguoio.getSelectedItem().toString();
        this.btcq = new BieuThucChinhQuy(motaloai, "[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
        if (!this.btcq.isBoolean()) {
            JOptionPane.showMessageDialog(them_loaiphong, "Mô tả loại phòng không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            them_loaiphong.tfmotaloaiphong.requestFocus();
        } else if (songuoio.equals("- Chọn số người ở -")) {
            JOptionPane.showMessageDialog(them_loaiphong, "Bạn chưa chọn số người ở.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            them_loaiphong.cbbsonguoio.requestFocus();
        } else {
            ObjectSet<LoaiPhong> loaiPhongs = this.conn.getConn().query(new Predicate<LoaiPhong>() {
                @Override
                public boolean match(LoaiPhong et) {
                    return et.getMotaloai().equals(motaloai);
                }
            });
            if (loaiPhongs.size() == 0) {
                LoaiPhong loaiPhong = new LoaiPhong(idloaiphong, motaloai, (byte) Integer.parseInt(songuoio));
                this.conn.getConn().store(loaiPhong);
                return true;
            } else {
                JOptionPane.showMessageDialog(them_loaiphong, "Loại phòng này đã tồn tại trong CSDL.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                them_loaiphong.tfmotaloaiphong.requestFocus();
            }
        }
        return false;
    }

    public boolean Edit(f_nhanvien_chunhatro_qlgiaphong sua_loaiphong) {
        final int idloaiphong = Integer.parseInt(sua_loaiphong.tfidloaiphong.getText());
        String motaloai =  XuLyChuoi.inHoaChuDauChuoi(sua_loaiphong.tfmotaloaiphong.getText());
        String songuoio = sua_loaiphong.cbbsonguoio.getSelectedItem().toString();
        this.btcq = new BieuThucChinhQuy(motaloai, "[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
        if (!this.btcq.isBoolean()) {
            JOptionPane.showMessageDialog(sua_loaiphong, "Mô tả loại phòng không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            sua_loaiphong.tfmotaloaiphong.requestFocus();
        } else if (songuoio.equals("- Chọn số người ở -")) {
            JOptionPane.showMessageDialog(sua_loaiphong, "Bạn chưa chọn số người ở.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            sua_loaiphong.cbbsonguoio.requestFocus();
        } else {
            ObjectSet<LoaiPhong> loaiPhongs = this.conn.getConn().query(new Predicate<LoaiPhong>() {
                @Override
                public boolean match(LoaiPhong et) {
                    return et.getIdloaiphong() != idloaiphong && et.getMotaloai().equals(motaloai);
                }
            });
            if (loaiPhongs.size() == 0) {
                LoaiPhong loaiPhong = this.conn.getConn().query(new Predicate<LoaiPhong>() {
                    @Override
                    public boolean match(LoaiPhong et) {
                        return et.getIdloaiphong() == idloaiphong;
                    }
                }).next();
                loaiPhong.setSucchua((byte) Integer.parseInt(songuoio));
                loaiPhong.setMotaloai(motaloai);
                this.conn.getConn().store(loaiPhong);
                return true;
            } else {
                JOptionPane.showMessageDialog(sua_loaiphong, "Loại phòng này đã tồn tại trong CSDL.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                sua_loaiphong.tfmotaloaiphong.requestFocus();
            }

        }
        return false;
    }

    public boolean Delete(int idloaiphong) {
        try {
            ObjectSet<LoaiPhong> xoa = this.conn.getConn().query(new Predicate<LoaiPhong>() {
                @Override
                public boolean match(LoaiPhong et) {
                    return et.getIdloaiphong() == idloaiphong;
                }
            });
            while (xoa.hasNext()) {
                LoaiPhong phongTro = xoa.next();
                if (phongTro.getDsphong().isEmpty() && phongTro.getDschitietgia().isEmpty()) {
                    this.conn.getConn().delete(phongTro);
                } else {
                    return false;
                }
            }
            return true;
        } catch (Db4oIOException | DatabaseClosedException | DatabaseReadOnlyException | HeadlessException ex) {
            return false;
        }
    }
}
